package com.study.manage.mvc.org.register;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.study.manage.dal.EvaluateApplyRepository;
import com.study.manage.dal.EvaluateApplyTeamDetailRepository;
import com.study.manage.dal.EvaluateApplyTeamRepository;
import com.study.manage.dal.EvaluateApplyWorkRepository;
import com.study.manage.dal.EvaluatePriceRepository;
import com.study.manage.dal.EvaluateRepository;
import com.study.manage.dal.NotificationRepository;
import com.study.manage.dal.OrderRepository;
import com.study.manage.dal.OrdersRepository;
import com.study.manage.dal.UserOrganizaRepository;
import com.study.manage.dal.UserRepository;
import com.study.manage.domain.Evaluate;
import com.study.manage.domain.EvaluateApply;
import com.study.manage.domain.EvaluateApplyTeam;
import com.study.manage.domain.EvaluateApplyTeamDetail;
import com.study.manage.domain.EvaluatePrice;
import com.study.manage.domain.Notification;
import com.study.manage.domain.Order;
import com.study.manage.domain.Orders;
import com.study.manage.domain.User;
import com.study.manage.domain.enumm.EAState;
import com.study.manage.domain.enumm.EvaluateApplyType;
import com.study.manage.domain.enumm.EvaluateVerify;
import com.study.manage.domain.enumm.ItemType;
import com.study.manage.domain.enumm.JpushTarget;
import com.study.manage.domain.enumm.LiveDieState;
import com.study.manage.domain.enumm.NotificationShowType;
import com.study.manage.domain.enumm.NotificationState;
import com.study.manage.domain.enumm.NotificationType;
import com.study.manage.domain.enumm.OrderState;
import com.study.manage.domain.enumm.OrdersType;
import com.study.manage.domain.enumm.PayState;
import com.study.manage.dto.AjaxResponse;
import com.study.manage.dto.JsonResponseBean;
import com.study.manage.mvc.common.BaseController;
import com.study.manage.mvc.common.CommonService;
import com.study.manage.utils.MapUtils;

@Controller
@RequestMapping("org/evaluate/detail/baoming")
public class EvaluateBaomingController extends BaseController {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserOrganizaRepository userOrganizaRepository;
    @Autowired
    private EvaluatePriceRepository evaluatePriceRepository;
    @Autowired
    private EvaluateApplyRepository evaluateApplyRepository;
    @Autowired
    private EvaluateApplyWorkRepository evaluateApplyWorkRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private CommonService commonService;
    @Autowired
    private EvaluateRepository evaluateRepository;
    @Autowired
    private NotificationRepository notificationRepository;

    @RequestMapping(path = "info", method = RequestMethod.GET)
    public String info() {
        return "org/evaluate/baoming";
    }

    /**
     * Get table Data
     * 
     */
    @ResponseBody
    @RequestMapping(path = "getTableData", method = RequestMethod.GET)
    public AjaxResponse info_list(Long evaluateId, String name, EvaluateVerify verify,
            EAState state, Integer flg, @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginAt,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endAt,
            @PageableDefault(sort = {"createdAt"}, direction = Direction.DESC) Pageable pageable) {

        AjaxResponse ajax = new AjaxResponse(true);
        List<Long> evaluateIds = new ArrayList<>(Arrays.asList(evaluateId));
        Map<String, Date> timeMap = commonService.getTimes(beginAt, endAt, evaluateIds, flg);
        beginAt = timeMap.get("beginAt");
        endAt = timeMap.get("endAt");
        session.setAttribute("beginAt", beginAt);
        session.setAttribute("endAt", endAt);
        Page<EvaluateApply> page = evaluateApplyRepository.findEvaluateApplys(evaluateId, beginAt,
                endAt, name, verify, state, null, pageable);
        return ajax.setObj(page.map(new Converter<EvaluateApply, Map<String, Object>>() {
            @Override
            public Map<String, Object> convert(EvaluateApply source) {
                Map<String, Object> map = MapUtils.convert(source);
                User user = userRepository.findOne(source.userId);
                map.put("userNumber", user.number);
                map.put("userName", user.name);
                if (source.verify != null)
                    map.put("verifyDesc", source.verify.desc);
                map.put("stateDesc", source.state.desc);
                if (source.referenceId != null) {
                    User refUer = userRepository.findOne(source.referenceId);
                    map.put("refName", refUer.name);
                } else {
                    map.put("refName", "--");
                }
                if (source.evaluatePriceId != null) {
                    EvaluatePrice ep = evaluatePriceRepository.findOne(source.evaluatePriceId);
                    map.put("epName", ep.title + "(" + ep.charge + ")");
                } else {
                    map.put("epName", "--");
                }
                Order order = orderRepository.findByItemTypeAndItemIdAndUserId(
                        ItemType.EvaluateSignup, source.evaluateId, source.userId);
                if (order != null) {
                    map.put("orderItemPrice", order.itemPrice);
                } else {
                    map.put("orderItemPrice", "--");
                }
                return map;
            }
        }));
    }


    @ResponseBody
    @RequestMapping(path = "info-detail-count", method = RequestMethod.GET)
    public AjaxResponse list_detail_count(Long evaluateId) {

        AjaxResponse ajax = new AjaxResponse(true);
        Date date = new Date();
        List<Long> es = Arrays.asList(evaluateId);
        Map<String, Object> map = new HashMap<>();
        map.put("bmCount", evaluateApplyRepository.countByEvaluateIdAndDay(evaluateId, null));
        map.put("bmCountDay", evaluateApplyRepository.countByEvaluateIdAndDay(evaluateId, date));
        map.put("successCount",
                evaluateApplyRepository.countSuccessByEvaluateId(evaluateId, null, null));
        map.put("successCountDay",
                evaluateApplyRepository.countSuccessByEvaluateId(evaluateId, date, null));
        map.put("passCount", evaluateApplyRepository.countByEvaluateIdAndVerify(evaluateId,
                EvaluateVerify.Pass, null));
        map.put("passCountDay", evaluateApplyRepository.countByEvaluateIdAndVerify(evaluateId,
                EvaluateVerify.Pass, date));
        map.put("waitCount", evaluateApplyRepository.countByEvaluateIdAndVerify(evaluateId,
                EvaluateVerify.Waiting, null));
        map.put("waitCountDay", evaluateApplyRepository.countByEvaluateIdAndVerify(evaluateId,
                EvaluateVerify.Waiting, date));
        map.put("workApplyCount", evaluateApplyWorkRepository.countByEvaluateIdInAndDay(es, null));
        map.put("workApplyCountDay",
                evaluateApplyWorkRepository.countByEvaluateIdInAndDay(es, date));
        Float orderSum = orderRepository.sumPriceByEvaluateIdIn(es, null);
        Float orderSumDay = orderRepository.sumPriceByEvaluateIdIn(es, date);
        map.put("orderSum", orderSum == null ? 0 : orderSum);
        map.put("orderSumDay", orderSumDay == null ? 0 : orderSumDay);
        return ajax.setObj(map);
    }

    @ResponseBody
    @Transactional
    @RequestMapping(path = "updateapply", method = RequestMethod.POST)
    public JsonResponseBean updateEvaluateApply(Long id, EvaluateVerify verify) {

        String msg = "";
        EvaluateApply evaluateApply = evaluateApplyRepository.findOne(id);
        Evaluate e = evaluateRepository.findOne(evaluateApply.evaluateId);
        if (EvaluateVerify.Pass.equals(verify)) {
            msg = "您报名的" + e.title + "比赛提交的报名资料已通过审核，请尽快上传您的参赛作";
            if (evaluateApply.evaluatePriceId != null) {
                EvaluatePrice ep = evaluatePriceRepository.findOne(evaluateApply.evaluatePriceId);
                if (!e.ifNeedPay || "0.00".equals(ep.charge)) {
                    if ("0.00".equals(ep.charge)) {
                        Order order = orderRepository.findByItemTypeAndItemIdAndUserId(
                                ItemType.EvaluateSignup, evaluateApply.evaluateId,
                                evaluateApply.userId);
                        if (order != null) {
                            order.state = OrderState.PAID;
                            orderRepository.save(order);
                        }
                    }
                    evaluateApplyRepository.update(id, verify, EAState.LIVE, new Date());
                } else {
                    evaluateApplyRepository.update(id, verify);
                }
            } else {
                evaluateApplyRepository.update(id, verify, EAState.LIVE, new Date());
            }
        } else {
            msg = "您报名的" + e.title + "比赛提交的报名资料未通过审核，请重新修改资料并提交。如有疑问可私信我要学官方号。";
            evaluateApplyRepository.update(id, verify);
        }

        User user = userRepository.findOne(evaluateApply.userId);
        Notification notification = new Notification();
        notification.type = NotificationType.SYS;
        notification.state = NotificationState.UNREAD;
        notification.name = "我要学";
        notification.avatar = "001";
        notification.userId = user.id;
        notification.showType = NotificationShowType.TEXT;
        notification.msg = msg;
        notificationRepository.save(notification);

        sendJpush(user.number + "", msg, JpushTarget.BS, evaluateApply.evaluateId.toString());
        return new JsonResponseBean(true);
    }
    //
    // @RequestMapping(path = "exportExecl", method = RequestMethod.GET)
    // public void exportExecl(Long id,HttpServletResponse response) throws Exception {
    //
    // String[] lables = commonService.getLables(id,1);
    // String[] parentLables = commonService.getLables(id,0);
    // Date beginAt = (Date) session.getAttribute("beginAt");
    // Date endAt = (Date) session.getAttribute("endAt");
    // List<EvaluateApply> list =
    // evaluateApplyRepository.findEvaluateApplys(id,beginAt,endAt,null,null);
    // StringBuilder context = new StringBuilder("报名时间,参赛编号,用户(ID),姓名,电话,组别,渠道");
    // for (String lable : lables) {
    // context.append(",").append(lable);
    // }
    // for (String parentLable : parentLables) {
    // context.append(",").append(parentLable);
    // }
    // context.append(",报名状态,付款状态,票种,付款,推荐方姓名,推荐方电话,推荐方地址\n");
    // for(EvaluateApply source : list) {
    // User user = userRepository.findOne(source.userId);
    // String refName = "";
    // String epName= "";
    // String itemPrice= "";
    // String sourceVerifyDesc = "";
    // String tjName = "";
    // String tjPhone = "";
    // String tjAddress = "";
    // if (source.referenceId != null) {
    // User refUer = userRepository.findOne(source.referenceId);
    // refName = refUer.name;
    // if(UserType.TEACHER==refUer.type){
    // tjPhone = refUer.phone==null?"":refUer.phone;
    // tjName = refUer.name==null?"":refUer.name ;
    // tjAddress = "";
    // }else{
    // UserOrganiza userOrganiza = userOrganizaRepository.findByUserId(source.referenceId);
    // tjName = userOrganiza.name==null?"":userOrganiza.name;
    // tjAddress = userOrganiza.mailAddress==null?"":userOrganiza.mailAddress;
    // User zcUser = userRepository.findOne(userOrganiza.regUserId);
    // tjPhone = zcUser.phone==null?"":zcUser.phone;
    // }
    // }
    // if(source.verify!=null) {
    // sourceVerifyDesc = source.verify.desc;
    // }
    // if (source.evaluatePriceId != null) {
    // EvaluatePrice ep = evaluatePriceRepository.findOne(source.evaluatePriceId);
    // epName = ep.title + "(" + ep.charge + ")";
    // }
    // Order order = orderRepository.findByItemTypeAndItemIdAndUserId(ItemType.EvaluateSignup,
    // source.evaluateId, source.userId);
    // if (order != null) {
    // itemPrice = order.itemPrice;
    // }
    // context.append(CmnDateUtil.formatDate(source.createdAt.toString())).append(",")
    // .append(source.number+"\t").append(",")
    // .append(user.name+"("+user.number+")").append(",")
    // .append(source.fullName==null ? "" : source.fullName).append(",")
    // .append(source.phone==null ? "" : source.phone).append(",")
    // .append(source.groupName==null ? "" : source.groupName).append(",")
    // .append(refName);
    // Map<String, Object> textMap = jsonMapper.fromJson(source.text, Map.class);
    // if(textMap == null) textMap = new HashMap<>();
    // for (String lable : lables) {
    // String value = (String) textMap.get(lable);
    // context.append(",").append(value == null ? "" : value.replace(",", "，"));
    // }
    // Map<String, Object> parentTextMap = jsonMapper.fromJson(source.parentText, Map.class);
    // if (parentTextMap == null) parentTextMap = new HashMap<>();
    // for (String parentLable : parentLables) {
    // String va = (String) parentTextMap.get(parentLable);
    // context.append(",").append(va == null ? "" : va);
    // }
    // context.append(",").append(sourceVerifyDesc).append(",")
    // .append(source.state.desc).append(",")
    // .append(epName).append(",")
    // .append(itemPrice).append(",")
    // .append(tjName).append(",")
    // .append(tjPhone).append(",")
    // .append(tjAddress).append("\n");
    // };
    // String nowDate =
    // "报名管理("+DateTimeUtil.getYYmmDD(beginAt)+"-"+DateTimeUtil.getYYmmDD(endAt)+").csv";
    // String fileName = new String(nowDate.getBytes("UTF-8"), "iso-8859-1");// 为了解决中文名称乱码问题
    // OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
    // // 要输出的内容
    // response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
    // osw.write(new String(new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
    // osw.write(context.toString());
    // osw.flush();
    // }


    @Autowired
    private OrdersRepository ordersRepository;
    @Autowired
    private EvaluateApplyTeamRepository evaluateApplyTeamRepository;
    @Autowired
    private EvaluateApplyTeamDetailRepository evaluateApplyTeamDetailRepository;

    @RequestMapping(path = "exportExecl", method = RequestMethod.GET)
    public void list_applyExport(Long id, @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginAt,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endAt, HttpServletResponse response)
                    throws Exception {
        Evaluate evaluate = evaluateRepository.findOne(id);
        String[] lables = converLabels(evaluate.labels);
        String[] teamLables = converLabels(evaluate.teamLabels);
        String[] parentLables = converLabels(evaluate.parentInfoLabels);
        StringBuilder context =
                new StringBuilder("报名时间,参赛编号,用户(ID),报名类型,节目,姓名,电话,组别,渠道,审核状态,报名状态,付款状态,订单编号,票种,付款");
        for (String lable : teamLables) {
            context.append(",").append(lable);
        }
        for (String lable : lables) {
            context.append(",").append(lable);
        }
        for (String parentLable : parentLables) {
            context.append(",").append(parentLable);
        }
        context.append("\n");
        List<EvaluateApply> evaluateApplys = evaluateApplyRepository
                .findByEvaluateIdAndNotDraftAndBeginAtDate(id, null, beginAt, endAt);

        for (EvaluateApply apply : evaluateApplys) {
            User user = userRepository.findOne(apply.userId);
            User ref = null;
            if (apply.referenceId != null) {
                ref = userRepository.findById(apply.referenceId);
            }

            PayState payState = PayState.DZF;
            Float payMoney = 0f;
            List<Orders> os = ordersRepository.findByTypeAndExtId(OrdersType.BSBM, apply.id);
            String orderNo = "--";
            if (!os.isEmpty()) {
                payState = os.get(0).payState;
                payMoney = os.get(0).total;
                orderNo = os.get(0).orderNo;
            }
            String epString = "";
            if (apply.evaluatePriceId != null) {
                EvaluatePrice ep = evaluatePriceRepository.findOne(apply.evaluatePriceId);
                if (ep != null) {
                    epString = new StringBuffer().append(ep.title).append("(").append(ep.charge)
                            .append(")").toString();
                }
            }
            context.append(DateFormatUtils.format(apply.createdAt, "yyyy.MM.dd")).append(",")
                    .append(apply.number).append(",").append(user.name + "(" + user.number + ")")
                    .append(",").append(apply.type.desc).append(",")
                    .append(apply.itemName == null ? "" : apply.fullName).append(",")
                    .append(apply.fullName == null ? "" : apply.fullName).append(",")
                    .append(apply.phone == null ? "" : apply.phone).append(",")
                    .append(apply.groupName == null ? "" : apply.groupName).append(",")
                    .append(ref == null ? "--" : ref.name).append(",").append(apply.verify.desc)
                    .append(",").append(apply.state.desc).append(",").append(payState.desc)
                    .append(",").append(orderNo).append(",").append(epString).append(",")
                    .append(payMoney);

            coverApplyString(context, teamLables, apply.text, lables, apply.text, parentLables,
                    apply.parentText);
            context.append("\n");
            if (apply.type == EvaluateApplyType.TEAM) {
                List<EvaluateApplyTeam> eats = evaluateApplyTeamRepository
                        .findByEvaluateApplyIdAndState(apply.id, LiveDieState.LIVE);

                for (EvaluateApplyTeam eat : eats) {
                    List<Orders> teamOs =
                            ordersRepository.findByTypeAndExtId(OrdersType.TTBSBM, eat.id);
                    PayState payStateTeam = PayState.DZF;
                    Float payMoneyTeam = 0f;
                    String orderNoTeam = "--";
                    if (!teamOs.isEmpty()) {
                        payStateTeam = teamOs.get(0).payState;
                        payMoneyTeam = teamOs.get(0).total;
                        orderNoTeam = teamOs.get(0).orderNo;
                    }
                    List<EvaluateApplyTeamDetail> eatds = evaluateApplyTeamDetailRepository
                            .findByEvaluateApplyTeamIdAndState(eat.id, LiveDieState.LIVE);

                    for (int i = 0; i < eatds.size(); i++) {
                        EvaluateApplyTeamDetail eatd = eatds.get(i);
                        context.append("").append(",").append("").append(",").append("").append(",")
                                .append("团体成员").append("").append(",").append(",")
                                .append(eatd.fullName == null ? "" : eatd.fullName).append(",")
                                .append(eatd.phone == null ? "" : eatd.phone).append(",")
                                .append(eatd.groupName == null ? "" : eatd.groupName).append(",")
                                .append("");

                        if (i == 0) {
                            context.append(",").append(eat.verify.desc).append(",").append("--")
                                    .append(",").append(payStateTeam.desc).append(",")
                                    .append(orderNoTeam).append(",").append("").append(",")
                                    .append(payMoneyTeam);
                        } else {
                            context.append(",").append("").append(",").append("").append(",")
                                    .append("").append(",").append(",").append("").append("")
                                    .append(",").append(payMoney);
                        }
                        coverApplyString(context, teamLables, null, lables, eatd.text, parentLables,
                                null);
                        context.append("\n");
                    }
                }
            }
        }
        this.export(evaluate.title + "_报名", context.toString(), response);
    }

    @SuppressWarnings("unchecked")
    private String[] converLabels(String labelsJson) {
        String[] lables = new String[0];
        List<Map<String, Object>> ls = jsonMapper.fromJson(labelsJson, List.class);
        if (ls != null) {
            lables = new String[ls.size()];
            for (int i = 0; i < ls.size(); i++) {
                Map<String, Object> l = ls.get(i);
                lables[i] = l.get("name").toString();
            }
        } else {
            if (!StringUtils.isEmpty(labelsJson)) {
                lables = labelsJson.split(",");
            }
        }
        return lables;
    }

    @SuppressWarnings("unchecked")
    private void coverApplyString(StringBuilder context, String[] teamLables, String teamText,
            String[] lables, String text, String[] parentLables, String parantText) {
        Map<String, Object> textMap = jsonMapper.fromJson(teamText, Map.class);
        if (textMap == null) {
            textMap = new HashMap<>();
        }
        for (String lable : teamLables) {
            String va = (String) textMap.get(lable);
            context.append(",").append(va == null ? "" : va.replace(",", "，"));
        }
        textMap = jsonMapper.fromJson(text, Map.class);
        if (textMap == null) {
            textMap = new HashMap<>();
        }
        for (String lable : lables) {
            String va = (String) textMap.get(lable);
            context.append(",").append(va == null ? "" : va.replace(",", "，"));
        }
        textMap = jsonMapper.fromJson(parantText, Map.class);
        if (textMap == null) {
            textMap = new HashMap<>();
        }
        for (String parentLable : parentLables) {
            String va = (String) textMap.get(parentLable);
            context.append(",").append(va == null ? "" : va.replace(",", "，"));
        }
    }

}


